<script setup lang="ts">
import type { ButtonOnGetphonenumberEvent } from '@uni-helper/uni-app-types'
import { useThrottleFn } from '@vueuse/core'
import { userLoginAPI } from '@/apis/userLogin'
import { useUserInfoStore } from '@/store/userInfo'
import { authorizePhoneAPI } from '@/apis/authorizePhone'
import { adminLoginAPI } from '@/apis/adminLogin'
import { empowerWechatAPI } from '@/apis/empowerWechat'

import wechatIcon from '@/static/images/wechat.png'

const router = useRouter()
const userInfoStore = useUserInfoStore()

// 是否为管理员，如果是则使用密码登录，否则使用微信一键登录。
// 该值从路由参数中获取。
const isAdmin = ref(false)

// 是否同意服务协议与隐私政策。
const isAgree = ref(false)

// 点击提交时进入 loading 状态。
const loading = ref(false)

// 管理员登录后没有授权微信，弹窗状态
const isShowEmpowerModal = ref(false)

// 收集到的表单数据。
const formData = ref({
  account: '',
  password: '',
})

// 表单组件 ref
const formRef = ref<any>(null)

// admin 提交按钮是否被禁用
const submitButtonDisabled = computed(() => {
  return !(formData.value.account && formData.value.password)
})

// 表单校验规则
const rules = {
  account: [
    {
      pattern: /^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\d{8}$/,
      message: '请输入正确的手机号',
      trigger: ['blur'],
    },
    { required: true, message: '手机号不可为空', trigger: ['blur', 'change'] },
  ],
  password: [
    { required: true, message: '密码不可为空', trigger: ['blur', 'change'] },
  ],
}

// 获取页面路由参数。
onLoad((options) => {
  if (options && options.group_id)
    isAdmin.value = options.group_id !== '0'
})

/**
 * @description 处理查看用户协议的事件，跳转至协议页面。
 *
 * @param keyword - 用于加载对应内容。
 */
function handleViewProtocol(keyword: string) {
  router.push({ name: 'protocol', params: { keyword } })
}

/**
 * @description 处理用户一键登录事件。
 */
const handleUserLogin = useThrottleFn(async (e: ButtonOnGetphonenumberEvent) => {
  if (!isAgree.value) {
    uni.showToast({ title: '请先勾选用户协议和隐私政策', icon: 'none' })
    return
  }
  if (!(e.detail && e.detail.iv && e.detail.encryptedData)) {
    uni.showToast({ title: '登录失败，请稍后重试', icon: 'none' })
    return
  }
  loading.value = true
  try {
    // 获取登录所需 code
    const loginRes = await uni.login()
    // 使用 code 和加密数据换取 userInfo
    const res = await userLoginAPI({
      code: loginRes.code,
      iv: e.detail.iv,
      encryptedData: e.detail.encryptedData,
    })
    const userInfo = res.data?.data.userinfo

    if (userInfo?.mobile) {
      // userInfo 中已有手机号，直接保存 userInfo 并跳转
      userInfoStore.setUserInfo(userInfo)
      router.replaceAll('userHome')
    }
    else {
      // userInfo 中没有手机号，再次获取 code
      const loginRes2 = await uni.login()
      // 使用 code 和加密数据换取手机号
      const authPhoneRes = await authorizePhoneAPI({
        code: loginRes2.code,
        iv: e.detail.iv,
        encryptedData: e.detail.encryptedData,
      }, userInfo?.token || '')
      const phoneNumber = authPhoneRes.data?.data
      if (phoneNumber) {
        // 将手机号与 userInfo 拼成一个包含手机号的新的 userInfo
        const userInfoWithPhoneNumber: UserInfo = { ...userInfo, mobile: phoneNumber }
        // 保存 userInfo 并跳转
        userInfoStore.setUserInfo(userInfoWithPhoneNumber)
        router.replaceAll('userHome')
      }
      else {
        uni.showToast({ title: `登录失败，请稍后重试`, icon: 'none' })
      }
    }
    loading.value = false
  }
  catch (error) {
    uni.showToast({ title: `登录失败，请稍后重试，${error}`, icon: 'none' })
    loading.value = false
  }
}, 1000)

/**
 * @description 处理内部人员登录事件。
 */
const handleAdminLogin = useThrottleFn(() => {
  if (!isAgree.value) {
    uni.showToast({ title: '请先勾选用户协议和隐私政策', icon: 'none' })
    return
  }
  formRef.value.validate()
    .then(async () => {
      // 表单校验通过，开始登录
      loading.value = true
      try {
        // 调用登录 API
        const res = await adminLoginAPI({
          account: formData.value.account,
          password: formData.value.password,
        })
        if (res.data?.code === 1) {
          // 服务器返回数据正常
          const userInfo = res.data.data.userinfo

          loading.value = false
          userInfoStore.setUserInfo(userInfo)

          if (!userInfo.applets_openid && userInfoStore.belongTo(['1', '2', '4'])) {
            isShowEmpowerModal.value = true
            return
          }

          router.replaceAll('adminHome')
        }
        else {
          // 服务器返回错误信息
          loading.value = false
          uni.showToast({ title: res.data?.msg, icon: 'none' })
        }
      }
      catch (err) {
        // 请求失败
        loading.value = false
        uni.showToast({ title: `登录失败，错误原因：${JSON.stringify(err)}`, icon: 'none' })
      }
    })
    .catch((errors: AnyObject[]) => {
      // 表单校验失败
      if (errors.length > 0)
        uni.showToast({ title: errors[0].message, icon: 'none' })
    })
}, 1000)

/**
 * @description 弹窗中为管理人员账号授权微信
 */
const handleEmpowerWechat = useThrottleFn(async (e: ButtonOnGetphonenumberEvent) => {
  try {
    const loginRes = await uni.login()
    const res = await empowerWechatAPI({
      code: loginRes.code,
      iv: e.detail.iv!,
      encryptedData: e.detail.encryptedData!,
    }, userInfoStore.userInfo!.token!)
    if (res.data?.code === 1)
      router.replaceAll('adminHome')
    else
      uni.showToast({ title: res.data?.msg, icon: 'none' })
  }
  catch (err) {
    uni.showToast({ title: JSON.stringify(err), icon: 'none' })
  }
}, 1000)
</script>

<template>
  <view class="absolute flex flex-col items-center w-full" :class="[isAdmin ? 'top-188rpx' : 'top-338rpx']">
    <!-- Logo -->
    <view class="flex justify-center items-center w-120rpx h-120rpx bg-brand rounded-large">
      <image class="w-103rpx h-85rpx" src="@/static/images/login/logo.png" />
    </view>
    <Spacer height="36" />
    <!-- 欢迎语 -->
    <view class="text-primary text-36rpx leading-36rpx font-bold">
      欢迎登录佳宅通小程序
    </view>
    <!-- 账号密码表单 -->
    <uv-form v-if="isAdmin" ref="formRef" :model="formData" :rules="rules">
      <Spacer height="60" />
      <!-- 账号 -->
      <uv-form-item prop="account" :custom-style="{ padding: 0 }">
        <uv-input
          v-model="formData.account"
          type="digit"
          :clearable="true"
          placeholder="请输入您的手机号"
          shape="circle"
          :custom-style="{ width: '630rpx', padding: '30rpx 40rpx', border: 'none', backgroundColor: '#F8F8F8', fontSize: '28rpx', lineHeight: '28rpx', fontWeight: 'medium', color: '#333333' }"
          :placeholder-style="{ fontSize: '28rpx', lineHeight: '28rpx', fontWeight: 'medium', color: '#999999' }"
        >
          <template #prefix>
            <image class="w-44rpx h-44rpx" src="@/static/images/login/account-input-prefix-icon.png" />
          </template>
        </uv-input>
      </uv-form-item>
      <Spacer height="30" />
      <!-- 密码 -->
      <uv-form-item prop="password" :custom-style="{ padding: 0 }">
        <uv-input
          v-model="formData.password"
          type="password"
          :clearable="true"
          placeholder="请填写您的密码"
          shape="circle"
          :custom-style="{ width: '630rpx', padding: '30rpx 40rpx', border: 'none', backgroundColor: '#F8F8F8', fontSize: '28rpx', lineHeight: '28rpx', fontWeight: 'medium', color: '#333333' }"
          :placeholder-style="{ fontSize: '28rpx', lineHeight: '28rpx', fontWeight: 'medium', color: '#999999' }"
        >
          <template #prefix>
            <image class="w-44rpx h-44rpx" src="@/static/images/login/password-input-prefix-icon.png" />
          </template>
        </uv-input>
      </uv-form-item>
      <Spacer height="70" />
      <!-- Admin Login Button -->
      <RGButton :loading="loading" :disabled="submitButtonDisabled" form-type="submit" @tap="handleAdminLogin">
        登录
      </RGButton>
    </uv-form>
  </view>
  <!-- User Login Button -->
  <RGButton v-if="!isAdmin" open-type="getPhoneNumber" :loading="loading" class="absolute bottom-210rpx x-center" @getphonenumber="handleUserLogin">
    用户快捷登录
  </RGButton>

  <!-- 用户协议 & 隐私政策 -->
  <view class="absolute bottom-135rpx x-center flex justify-center items-center w-full" @tap="isAgree = !isAgree">
    <Checkbox :checked="isAgree" />
    <Spacer width="9" />
    <view class="text-26rpx  text-tertiary">
      我已阅读并同意
      <text class="text-brand" @tap.stop="() => handleViewProtocol('fwxy')">
        《服务协议》
      </text>
      与
      <text class="text-brand" @tap.stop="() => handleViewProtocol('ysxy')">
        《隐私政策》
      </text>
    </view>
  </view>

  <uv-overlay :show="isShowEmpowerModal" @tap="isShowEmpowerModal = false">
    <uv-transition mode="zoom-in" :show="isShowEmpowerModal">
      <view class="relative w-screen h-screen">
        <JZTModal
          :icon="wechatIcon"
        >
          <Spacer height="146" />
          <view class="text-34rpx leading-34rpx font-bold text-center">
            绑定微信
          </view>
          <Spacer height="42" />
          <view class="text-#333333 text-28rpx leading-40rpx mx-103rpx text-center">
            为保证您获取精准的订阅消息推送，请先绑定微信
          </view>
          <Spacer height="52" />
          <RGButton :width="422" open-type="getPhoneNumber" @getphonenumber="handleEmpowerWechat">
            微信授权
          </RGButton>
          <Spacer height="100" />
        </JZTModal>
      </view>
    </uv-transition>
  </uv-overlay>
</template>

<route lang="yaml">
name: 'login'
style:
  navigationBarTitleText: '登录'
layout: 'custom'
</route>
